﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

using System.Reflection; // 使用 Assembly 类需用此 命名空间
using System.Reflection.Emit; // 使用 ILGenerator 需用此 命名空间

using System.Configuration;
using System.Management;
using System.IO;
using System.Threading;

namespace 充值取现卡制作软件
{
    public partial class FrmMain : Form
    {
        /*
         基本操作：0 自动连接串口
                   1 MifarePass读密码，密码来自数据库
                   2 RFMifare_GetSnr 读卡的序列号，读写数据的时候，需要序列号作为参数
                   3 RFMifare_ReadBlock  RFMifare_WriteBlock读写卡数据
             */
        [DllImport("CC200.dll")]
        public static extern int AutoLinkCom(out int port);//连接COM
        [DllImport("CC200.dll")]
        public static extern int UnConnectCom();//断开COM口
        [DllImport("CC200.dll")]
        public static extern int MifarePass(ulong password);//下载加密密码到读卡器
        [DllImport("CC200.dll")]
        public static extern int RFMifare_GetSnr(out uint snr);//读卡序列号
        [DllImport("CC200.dll")]
        public static extern uint Date2Seconds(out byte[] Sec);//获取当前时间距2006-01-01 00:00:00的秒数
        [DllImport("CC200.dll")]
        public static extern int InputDate2Seconds(out byte[] dt, out byte[] sec);//将传入的时间转换成秒
        [DllImport("CC200.dll")]
        public static extern int RFMifare_ReadBlock(int BlockNo, int CardSn, byte[] buf);//读卡片区的数据
        [DllImport("CC200.dll")]
        public static extern int RFMifare_WriteBlock(int BlockNo, int CardSn, byte[] buf);//写卡片区的数据
        [DllImport("CC200.dll")]
        public static extern byte buffer_crc1(byte st, byte len, byte[] buf);
        [DllImport("CC200.dll")]
        public static extern byte buffer_crc2(byte st, byte len, byte[] buf);
        [DllImport("CC200.dll")]
        public static extern int ALARM(int mode, int actiontime, int intervaltime, int count);//读卡成功发出语音
        [DllImport("CC200.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int YXJ_pass(ulong passWord);//下载密码
        [DllImport("CC200.dll")]
        public static extern int SK_Init_Card();
        [DllImport("CC200.dll")]
        public static extern void SetBlock(ulong BlockNo);//设置扇区
        [DllImport("CC200.dll")]
        public static extern long MifareInitPass();//下载初始密码
        [DllImport("CC200.dll", EntryPoint = "RFMifare_WriteKey", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]//写入密码
        public static extern int RFMifare_WriteKey(int Sector, int CardSn, byte[] Key, byte MLC);
        [DllImport("CC200.dll")]
        public static extern int MifarePass(uint pass);

        /// <summary>
        /// 自动读卡线程
        /// </summary>
        Thread autoReadThread = null;
        /// <summary>
        /// 写卡线程
        /// </summary>
        Thread writeThread = null;
        /// <summary>
        /// 卡序列号
        /// </summary>
        uint snr = 0;
        /// <summary>
        /// 卡密码
        /// </summary>
        ulong pwd = 0;
        /// <summary>
        /// 线程运行标志
        /// </summary>
        bool threadRunFlag = false;
        /// <summary>
        /// 充值卡标志，true为充值卡，false为取现卡
        /// </summary>
        bool topUpCard = true;
        /// <summary>
        /// 00：现金余额充值
        /// 01：现金余额取现
        /// 02：现金余额覆盖
        /// 03：补助余额充值
        /// 04：补助余额取现
        /// 05：补助余额覆盖
        /// </summary>
        byte operationSign = 0;
        /// <summary>
        /// 脉冲卡为true
        /// </summary>
        bool pluseCard = false;


        public FrmMain()
        {
            InitializeComponent();
        }

        private void butc50_Click(object sender, EventArgs e)
        {
            tbMoney.Text = "50";
        }

        private void butc100_Click(object sender, EventArgs e)
        {
            tbMoney.Text = "100";
        }

        private void butc200_Click(object sender, EventArgs e)
        {
            tbMoney.Text = "200";
        }

        private void butc300_Click(object sender, EventArgs e)
        {
            tbMoney.Text = "300";
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            int port = 0;
            int ret = 0;
            ret = AutoLinkCom(out port);

            if(ret != 0)
            {
                MessageBox.Show("端口打开失败！");
                Application.Exit();
                return;
            }

            ALARM(6, 20, 1, 1);//初始化成功读写器蜂鸣器发声

            pwd = (ulong)Convert.ToInt64(tbPassword.Text);

            cmbOperationSign.SelectedIndex = 0;

            timer1.Enabled = true;
            timer1.Interval = 200;
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnConnectCom();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            timer1.Interval = 100;

            if (threadRunFlag == false)
            {
                Thread th = new Thread(AutoReadCard);
                th.IsBackground = true;
                th.Start();
            }
            //    autoReadThread = new Thread(AutoReadCard);
            //autoReadThread.IsBackground = true;
            //autoReadThread.Start();

            timer1.Enabled = true;
        }
        /// <summary>
        /// 
        /// </summary>
        private void AutoReadCard()
        {
            lock(this)
            {
                while (threadRunFlag == true) ;
                threadRunFlag = true;
            }

            int ret = 0;
            int timerout = 0;
            byte[] buf = new byte[16];

            ret = RFMifare_GetSnr(out snr);//获取序列号  
            if ((ret == 0) && (snr != 0xFFFFFFFF))//如果读不到卡，即消除以前的序列号
            {
                
            }
            else
            {
                try
                {
                    this.Invoke(new EventHandler(delegate
                    {
                        txtSerialNo.Text = "";//清除
                        txtLeftCardMoney.Text = "";
                        latxt.Text = "提示：请放卡！";
                    }));
                    ButtonEnable(false);
                }
                catch { }

                threadRunFlag = false;
                return;
            }

            if((txtSerialNo.Text != "") &&(Convert.ToUInt32(txtSerialNo.Text) == snr))
            {
                threadRunFlag = false;
                return;
            }

            try
            {
                this.Invoke(new EventHandler(delegate
                {
                    txtSerialNo.Text = snr.ToString();//将序列号转为十六进制显示
                }));
            }
            catch { }

            //============================================
            //                  下面是读数据
            //============================================

            ALARM(6, 20, 1, 1);//初始化成功读写器蜂鸣器发声
            ret = MifarePass(pwd);// YXJ_pass(pwd);
            ret = RFMifare_ReadBlock(7 * 4 + 1, (int)snr, buf);
            if (ret != 0)
            {
                //判断是否为新卡
                SetBlock(7);
                //返回0即为新卡
                do
                {
                    ret = (int)MifareInitPass();
                    timerout++;
                } while ((ret != 0) && (timerout < 5));

                if (timerout < 5)
                {
                    try
                    {
                        //读不到数据，即为非法卡
                        this.Invoke(new EventHandler(delegate
                        {
                            latxt.Text = "提示：该卡为新卡！";
                        }));
                    }
                    catch { }

                    threadRunFlag = false;
                    //使能所有的按键
                    ButtonEnable(true);

                    return;
                }
            }

            
            

            timerout = 0;
            do
            {
                ret = RFMifare_ReadBlock(7*4+1, (int)snr, buf);//读卡片区的数据
                timerout++;
            } while ((ret != 0) && (timerout < 5));

            if(timerout >= 5)
            {
                try
                {
                    //读不到数据，即为非法卡
                    this.Invoke(new EventHandler(delegate
                    {
                        latxt.Text = "提示：该卡为非法卡！";
                    }));
                }
                catch { }
                threadRunFlag = false;
                return;
            }

            if ((buf[0] == 0x20) && (buf[1] == 0x8A)) pluseCard = true;
            else pluseCard = false;
            //==========================================
            //              下面读卡数据
            //==========================================
            int cardType = buf[0];
            int money = 0;

            timerout = 0;
            do
            {
                ret = RFMifare_ReadBlock(7 * 4 + 0, (int)snr, buf);//读卡片区的数据
                timerout++;
            } while ((ret != 0) && (timerout < 5));

            if (timerout >= 5)
            {
                try
                {
                    //读不到数据，即为非法卡
                    this.Invoke(new EventHandler(delegate
                    {
                        latxt.Text = "提示：该卡为非法卡！";
                    }));
                }
                catch { }
                threadRunFlag = false;
                return;
            }

            this.Invoke(new EventHandler(delegate
            {
                if (pluseCard == true) tbPluse.Text = (Convert.ToDouble(buf[0]) / 10).ToString("F1");
                else cmbOperationSign.SelectedIndex = buf[0];
            }));

            money = buf[1] * 256 * 256 * 256 + buf[2] * 256 * 256 + buf[3] * 256 + buf[4];

            if (cardType == 0x23)
            {
                try
                {
                    this.Invoke(new EventHandler(delegate
                    {
                        latxt.Text = "提示：该卡为充值卡！";
                        txtLeftCardMoney.Text = (Convert.ToDouble(money) / 100).ToString("F2");
                    }));
                }
                catch //(Exception ex)
                {

                }
            }
            else if(cardType == 0x24)
            {
                try
                {
                    this.Invoke(new EventHandler(delegate
                    {
                        latxt.Text = "提示：该卡为取现卡！";
                        txtLeftCardMoney.Text = Convert.ToDouble(money / 100).ToString("F2");
                    }));
                }
                catch
                { }
            }
            else if (cardType == 0x20)
            {
                try
                {
                    this.Invoke(new EventHandler(delegate
                    {
                        latxt.Text = "提示：该卡为脉冲系数卡！";
                        txtLeftCardMoney.Text = Convert.ToDouble(money / 100).ToString("F2");
                    }));
                }
                catch
                { }
            }
            else
            {
                try
                {
                    //读不到数据，即为非法卡
                    this.Invoke(new EventHandler(delegate
                    {
                        latxt.Text = "提示：该卡为非法卡！";
                    }));
                }
                catch { }
                //使能所有的按键
                ButtonEnable(false);

                threadRunFlag = false;

                return;
            }

            //使能所有的按键
            ButtonEnable(true);

            threadRunFlag = false;
        }

        private void ButtonEnable(bool flag)
        {
            this.Invoke(new EventHandler(delegate
            {
                butSetc.Enabled = flag;
                butSetq.Enabled = flag;
                butc50.Enabled = flag;
                butc100.Enabled = flag;
                butc200.Enabled = flag;
                butc300.Enabled = flag;
            }));
        }

        /// <summary>
        /// 写卡线程
        /// </summary>
        private void WriteCardThread()
        {
            lock (this)
            {
                while (threadRunFlag == true) ;
                threadRunFlag = true;
            }
            int ret = 0;
            byte[] buf = new byte[16];
            int timerout = 0;
            //byte[] readBuf = new byte[16];
            ////卡金额
            //uint cardMoney = 0;

            ret = YXJ_pass(pwd);

            //初始化卡
            ret = SK_Init_Card();
            if(ret >= 2)//((ret != 2)&&(ret != 1))
            {
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("初始化卡失败");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }

            //if(topUpCard == true)
            //{
            //    if((operationSign != 2) && (operationSign != 5))
            //    {
            //        timerout = 0;
            //        do {
            //            ret = RFMifare_ReadBlock(4 * 7 + 0, (int)snr, readBuf);
            //            timerout++;
            //        } while ((ret != 0) && (timerout < 3));
            //        if(timerout < 3)
            //        {
            //            cardMoney = readBuf
            //        }
            //    }
            //}

            //写入数据
            if (topUpCard == true)
            {//充值卡
                buf[0] = 0x23;
                buf[1] = 0x89;
            }
            else
            {//取现卡
                buf[0] = 0x24;
                buf[1] = 0x8E;
            }

            for(int i=2;i<14;i++)
            {
                buf[i] = 0;
            }

            buf[14] = (byte)buffer_crc1(0, 14, buf);
            buf[15] = (byte)buffer_crc2(0, 15, buf);

            timerout = 0;
            do
            {
                ret = RFMifare_WriteBlock(4*7+1, (int)snr, buf);//写卡片区的数据
                timerout++;
            } while ((ret !=0) &&(timerout < 5));

            if(timerout >= 5)
            {
                //写入失败，退出
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("卡写入失败");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }

            //写入金额
            if(topUpCard == true)
            {
                buf[0] = (byte)operationSign;// cmbOperationSign.SelectedIndex;//0x00;
            }
            else
            {
                buf[0] = 0x01;
            }

            double dMoney = Convert.ToDouble(tbMoney.Text) * 100;
            uint money = Convert.ToUInt32(dMoney);

            buf[1] = (byte)(money >> 24);
            buf[2] = (byte)(money >> 16);
            buf[3] = (byte)(money >> 8);
            buf[4] = (byte)(money);

            for(int i=5;i<14;i++)
            {
                buf[i] = 0;
            }

            buf[14] = (byte)buffer_crc1(0, 14, buf);
            buf[15] = (byte)buffer_crc2(0, 15, buf);

            timerout = 0;
            do
            {
                ret = RFMifare_WriteBlock(4 * 7 + 0, (int)snr, buf);//写卡片区的数据
                timerout++;
            } while ((ret != 0) && (timerout < 5));

            if (timerout >= 5)
            {
                //写入失败，退出
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("卡写入失败");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }

            ret = MifarePass(pwd);// YXJ_pass(pwd);

            //检查是否可以读出
            timerout = 0;
            do
            {
                ret = RFMifare_ReadBlock(4 * 7 + 1, (int)snr, buf);
                timerout++;
            } while ((ret != 0) && (timerout < 5));

            if (timerout >= 5)
            {
                //写入失败，退出
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("卡写入失败");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }


            this.Invoke(new EventHandler(delegate
            {
                MessageBox.Show("写入成功！");
                txtSerialNo.Text = "";
                timer1.Enabled = false;
                timer1.Interval = 10;
                timer1.Enabled = true;
            }));

            threadRunFlag = false;
        }

        private void tbPassword_TextChanged(object sender, EventArgs e)
        {
            if (tbPassword.Text == "") return;

            try
            {
                pwd = Convert.ToUInt64(tbPassword.Text);
            }
            catch
            {
                MessageBox.Show("输入有误，必须输入纯数字！");
            }
        }

        private void butSetc_Click(object sender, EventArgs e)
        {
            pluseCard = false;
            topUpCard = true;
            operationSign = (byte)cmbOperationSign.SelectedIndex;
            ButtonEnable(false);
            Thread th = new Thread(WriteCardThread);
            th.IsBackground = true;
            th.Start();

        }

        private void butSetq_Click(object sender, EventArgs e)
        {
            pluseCard = false;
            topUpCard = false;
            cmbOperationSign.SelectedIndex = 0x01;
            ButtonEnable(false);
            Thread th = new Thread(WriteCardThread);
            th.IsBackground = true;
            th.Start();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ButtonEnable(false);
            Thread th = new Thread(ClearCardThread);
            th.IsBackground = true;
            th.Start();
        }

        private void ClearCardThread()
        {
            lock (this)
            {
                while (threadRunFlag == true) ;
                threadRunFlag = true;
            }

            int timerout = 0;
            int ret = 0;
            byte[] buf = new byte[16];


            ret = RFMifare_GetSnr(out snr);//获取序列号  

            ret = MifarePass(pwd);// YXJ_pass(pwd);
            ret = RFMifare_ReadBlock(7 * 4 + 1, (int)snr, buf);
            if (ret != 0)
            {
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("密码错误");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }

            for (int i = 0; i < 16; i++)
            {
                buf[i] = 0xFF;
            }

            for(int sector=7;sector<10;sector++)
            {
                for (int block = 0; block < 3; block++)
                {
                    timerout = 0;
                    do
                    {
                        ret = RFMifare_WriteBlock((4* sector) + block, (int)snr, buf);
                        timerout++;
                    }
                    while ((ret != 0) && (timerout < 5));

                    if (timerout >= 5)
                    {
                        this.Invoke(new EventHandler(delegate
                        {
                            MessageBox.Show("密码错误");
                        }));
                        threadRunFlag = false;
                        ButtonEnable(true);
                        return;
                    }
                }
            }


            byte[] m = new byte[6];
            m[0] = 0xff;
            m[1] = 0xff;
            m[2] = 0xff;
            m[3] = 0xff;
            m[4] = 0xff;
            m[5] = 0xff;

            for (int sector = 7; sector < 10; sector++)
            {
                SetBlock((ulong)sector);

                timerout = 0;
                do
                {
                    ret = RFMifare_WriteKey(sector, (int)snr, m, 0);
                    timerout++;
                } while ((ret != 0) && (timerout < 5));

                if (timerout >= 5)
                {
                    this.Invoke(new EventHandler(delegate
                    {
                        MessageBox.Show("回收失败");
                    }));
                    ButtonEnable(true);
                    threadRunFlag = false;
                    return;
                }
            }


            this.Invoke(new EventHandler(delegate
            {
                MessageBox.Show("回收成功！");

                txtSerialNo.Text = "";
                txtLeftCardMoney.Text = "";
                timer1.Enabled = false;
                timer1.Interval = 10;
                timer1.Enabled = true;
            }));
            ButtonEnable(true);
            threadRunFlag = false;
        }


        private void WritePluseThread()
        {
            lock (this)
            {
                while (threadRunFlag == true) ;
                threadRunFlag = true;
            }
            int ret = 0;
            byte[] buf = new byte[16];
            int timerout = 0;

            ret = YXJ_pass(pwd);

            //初始化卡
            ret = SK_Init_Card();
            if (ret >= 2)//((ret != 2)&&(ret != 1))
            {
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("初始化卡失败");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }

            //写入卡类型
            buf[0] = 0x20;
            buf[1] = 0x8A;

            for (int i = 2; i < 14; i++)
            {
                buf[i] = 0;
            }

            buf[14] = (byte)buffer_crc1(0, 14, buf);
            buf[15] = (byte)buffer_crc2(0, 15, buf);

            timerout = 0;
            do
            {
                ret = RFMifare_WriteBlock(4 * 7 + 1, (int)snr, buf);//写卡片区的数据
                timerout++;
            } while ((ret != 0) && (timerout < 5));

            if (timerout >= 5)
            {
                //写入失败，退出
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("卡写入失败");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }


            //写入卡类型
            buf[0] = (byte)( Convert.ToDouble( tbPluse.Text.Trim()) * 10);
            if (buf[0] == 0) buf[0] = 1;//系数不能为0，因为在机器中作为被除数
            for (int i = 1; i < 14; i++)
            {
                buf[i] = 0;
            }

            buf[14] = (byte)buffer_crc1(0, 14, buf);
            buf[15] = (byte)buffer_crc2(0, 15, buf);


            timerout = 0;
            do
            {
                ret = RFMifare_WriteBlock(4 * 7 + 0, (int)snr, buf);//写卡片区的数据
                timerout++;
            } while ((ret != 0) && (timerout < 5));

            if (timerout >= 5)
            {
                //写入失败，退出
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("卡写入失败");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }


            ret = MifarePass(pwd);// YXJ_pass(pwd);

            //检查是否可以读出
            timerout = 0;
            do
            {
                ret = RFMifare_ReadBlock(4 * 7 + 1, (int)snr, buf);
                timerout++;
            } while ((ret != 0) && (timerout < 5));

            if (timerout >= 5)
            {
                //写入失败，退出
                this.Invoke(new EventHandler(delegate
                {
                    MessageBox.Show("卡写入失败");
                }));
                threadRunFlag = false;
                ButtonEnable(true);
                return;
            }

            this.Invoke(new EventHandler(delegate
            {
                MessageBox.Show("写入成功！");
                txtSerialNo.Text = "";
                timer1.Enabled = false;
                timer1.Interval = 10;
                timer1.Enabled = true;
            }));

            threadRunFlag = false;
        }

        private void btnWritePluse_Click(object sender, EventArgs e)
        {
            pluseCard = true;
            ButtonEnable(false);
            Thread th = new Thread(WritePluseThread);
            th.IsBackground = true;
            th.Start();
        }
    }
}
